package org.example.concurrent;

import java.util.concurrent.locks.LockSupport;

/**
 * LockSupport的使用
 * 线程间通信:
 * 当一个线程需要通知另一个线程继续执行时，它可以使用 unpark() 方法。
 * 任务调度:
 * 在线程池中，当需要唤醒空闲线程去执行新任务时，可以使用 unpark()。
 * 条件变量:
 * 在实现类似于 Condition 的功能时，可以使用 unpark() 和 park() 方法来实现线程间的等待和通知。
 */
public class LockSupportDemo {

    private Thread consumerThread;
    private final Object data;
    private volatile boolean isProduced = false;

    public LockSupportDemo(Object data) {
        this.data = data;
    }

    public void produce() throws InterruptedException {
        System.out.println("Producer producing data...");
        data.toString(); // 假设这里是实际的数据生产过程
        isProduced = true;
        System.out.println("Data produced.");
        LockSupport.unpark(consumerThread); // 唤醒消费者线程
    }

    public void consume() throws InterruptedException {
        while (!isProduced) {
            System.out.println("Consumer waiting for data...");
            LockSupport.park(); // 消费者线程等待
        }
        System.out.println("Consumer consuming data...");
        data.toString(); // 假设这里是实际的数据消费过程
        isProduced = false;
        System.out.println("Data consumed.");
    }

    public static void main(String[] args) throws InterruptedException {
        LockSupportDemo example = new LockSupportDemo(new Object());
        Thread producerThread = new Thread(() -> {
            try {
                example.produce();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }, "Producer");

        Thread consumerThread = new Thread(() -> {
            try {
                example.consume();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }, "Consumer");

        example.consumerThread = consumerThread; // 传递给 produce 方法

        producerThread.start();
        consumerThread.start();

        // 等待线程结束
        producerThread.join();
        consumerThread.join();
    }
}
